<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * session类修改
 * @author:Calvin
 *
 */




/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * Session Class
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Sessions
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/libraries/sessions.html
 */
class MY_Session extends CI_Session
{
	protected $ci;
	public function __construct(array $params = array())
	{
		$this->ci = & get_instance();
		parent::__construct($params);
	}
	/**
	 * Configuration
	 *
	 * Handle input parameters and configuration defaults
	 *
	 * @param	array	&$params	Input parameters
	 * @return	void
	 */
	protected function _configure(&$params)
	{
		$this->ci->config->load("rest");
		//$this->ci->load("rest");
		$this->ci->load->service("token_service");
		$get_key = config_item("rest_access_token_get_key");
		$token = $this->ci->input->get($get_key,TRUE);

		//$token = htmlspecialchars($_REQUEST[$get_key],ENT_QUOTES);

		$sid = $this->ci->input->get_post("_sid",TRUE);
		$cookie_sid = $this->ci->input->cookie("__SID__");

		$prev_id = session_id();
		if(!empty($token))
		{
			$parse_sid = $this->ci->token_service->parse_token($token);

			if($parse_sid && $parse_sid!=$prev_id && $this->session_valid_id($parse_sid))
			{
				session_id($parse_sid);
				/*$sess_key = config_item("rest_access_token_session_key");
				$sess = $this->userdata($sess_key);
				if(!$this->ci->token_service->token_valid($sess)){
					session_id($prev_id);
				}else if($sess['temp']){
					$this->sess_regenerate(TRUE);
				}*/
			}
		}else if(empty($cookie_sid) && !empty($sid) && $this->session_valid_id($sid) && $sid!=$prev_id){
			session_id($sid);
		}


		$expiration = config_item('sess_expiration');

		if (isset($params['cookie_lifetime']))
		{
			$params['cookie_lifetime'] = (int) $params['cookie_lifetime'];
		}
		else
		{
			$params['cookie_lifetime'] = ( ! isset($expiration) && config_item('sess_expire_on_close'))
				? 0 : (int) $expiration;
		}

		isset($params['cookie_name']) OR $params['cookie_name'] = config_item('sess_cookie_name');
		if (empty($params['cookie_name']))
		{
			$params['cookie_name'] = ini_get('session.name');
		}
		else
		{
			ini_set('session.name', $params['cookie_name']);
		}

		isset($params['cookie_path']) OR $params['cookie_path'] = config_item('cookie_path');
		isset($params['cookie_domain']) OR $params['cookie_domain'] = config_item('cookie_domain');
		isset($params['cookie_secure']) OR $params['cookie_secure'] = (bool) config_item('cookie_secure');

		session_set_cookie_params(
			$params['cookie_lifetime'],
			$params['cookie_path'],
			$params['cookie_domain'],
			$params['cookie_secure'],
			TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons
		);

		if (empty($expiration))
		{
			$params['expiration'] = (int) ini_get('session.gc_maxlifetime');
		}
		else
		{
			$params['expiration'] = (int) $expiration;
			ini_set('session.gc_maxlifetime', $expiration);
		}

		$params['match_ip'] = (bool) (isset($params['match_ip']) ? $params['match_ip'] : config_item('sess_match_ip'));

		isset($params['save_path']) OR $params['save_path'] = config_item('sess_save_path');

		$this->_config = $params;

		// Security is king
		ini_set('session.use_trans_sid', 0);
		ini_set('session.use_strict_mode', 1);
		ini_set('session.use_cookies', 1);
		ini_set('session.use_only_cookies', 1);
		ini_set('session.hash_function', 1);
		ini_set('session.hash_bits_per_character', 4);
	}
	/**
	 * 验证session id合法性
	 * @param $session_id
	 * @return bool
	 */
	public function session_valid_id($session_id)
	{
		return preg_match('/^[-,a-zA-Z0-9]{16,128}$/', $session_id) > 0;
		//return preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $session_id) > 0;
	}

	/**
	 * 设置全局session数据
	 * @param $session_id
	 * @param null $key
	 * @return bool
	 */
	public function global_userdata($session_id,$key=NULL)
	{
		if(!$this->session_valid_id($session_id))
		{
			return FALSE;
		}
		if(session_status()!=PHP_SESSION_ACTIVE)session_start();
		$current_id=session_id();
		session_write_close();
		session_id($session_id);
		session_start();
		$value=$_SESSION;
		if(isset($_SESSION[$key]))$value=$_SESSION[$key];
		session_write_close();
		session_id($current_id);
		session_start();
		return $value;
	}

	/**
	 *
	 * 设置全局session
	 * @param $session_id
	 * @param null $key
	 * @param null $value
	 * @return bool
	 */
	public function set_global_userdata($session_id,$key=NULL,$value=NULL)
	{
		if(!$this->session_valid_id($session_id))
		{
			return FALSE;
		}
		if(session_status()!=PHP_SESSION_ACTIVE)session_start();
		$current_id=session_id();
		session_write_close();
		session_id($session_id);
		session_start();
		if(isset($_SESSION[$key]))$_SESSION[$key]=$value;
		session_write_close();
		session_id($current_id);
		session_start();
		return TRUE;
	}

	/**
	 * 销毁全局指定的session
	 * @param $session_id
	 * @return bool
	 */
	public function global_destroy($session_id)
	{
		if(!$this->session_valid_id($session_id))
		{
			return FALSE;
		}
		if(session_status()!=PHP_SESSION_ACTIVE)session_start();
		$current_id=session_id();
		session_write_close();
		session_id($session_id);
		session_start();
		session_destroy();
		session_id($current_id);
		session_start();
		return TRUE;
	}
	public function sess_destroy($keep_sid=FALSE)
	{
		if(!$keep_sid)
		{
			session_destroy();
		}
		else
		{
			$current_id=session_id();
			session_destroy();
			session_id($current_id);
			session_start();
		}
	}

	public function new_session_id($sid="")
	{
		if(empty($sid))
		{
			$sid = Common::uniqid();
		}
		if(session_status()!=PHP_SESSION_ACTIVE)session_start();
		session_destroy();
		session_id($sid);
		session_start();
	}

	public function merge_userdata($key,$data)
	{
		$old = $this->userdata($key);
		if(is_array($old) && is_array($data))
		{
			$new = array_merge($old,$data);
		}
		else
		{
			$new = $data;
		}
		return $this->set_userdata($key,$new);
	}
}
// END Session Class

/* End of file Session.php */
/* Location: ./system/libraries/Session.php */